﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using GMap.NET;

namespace MyPoints
{
  /// <summary>
  /// Interaction logic for InputWindow.xaml
  /// </summary>
  public partial class InputWindow : Window
  {
    private const string INVALID_GPS = "--.----- --.-----";

    GMap.NET.PointLatLng? point = null;
    parserType[] parsers;
    int defaultParserTextIndex = 0;
    int defaultParserClipboardIndex = 0;

    public void Init()
    {
      parsers = Shared.sett.runtime.parsers;

      int i = 0;
      foreach (var p in parsers)
      {
        ComboBoxItem cbi = new ComboBoxItem();
        cbi.Content = p.title;
        cmbPatterns.Items.Add(cbi);
        if (p.isDefaultClipboardParserSpecified && p.isDefaultClipboardParser)
          defaultParserClipboardIndex = i;
        if (p.isDefaultTextParserSpecified && p.isDefaultTextParser)
          defaultParserTextIndex = i;

        i++;
      }

      cmbPatterns.SelectedIndex = defaultParserTextIndex;
      lblResult.Content = INVALID_GPS;
    }

    public InputWindow()
    {
      InitializeComponent();
    }

    internal void SetText(string inText)
    {
      txtText.Text = inText;
      cmbPatterns.SelectedIndex = defaultParserClipboardIndex;
    }

    internal PointLatLng? GetPointLatLng()
    {
      return point;
    }

    private void txtText_TextChanged(object sender, TextChangedEventArgs e)
    {
      UpdateResult();
    }

    private void cmbPatterns_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
      UpdateResult();
    }

    private void UpdateResult()
    {
      if (cmbPatterns.SelectedIndex < 0) return;
      string txt = txtText.Text;
      parserType p = parsers[cmbPatterns.SelectedIndex];

      Match m = Regex.Match(txt, p.regex);

      if (m.Success == false)
      {
        lblResult.Content = INVALID_GPS;
      }
      else
      {
        double latDeg;
        double latMin = 0;
        double latSec = 0;
        double lngDeg;
        double lngMin = 0;
        double lngSec = 0;
        bool isS = false;
        bool isW = false;

        latDeg = GetDoubleFromGroup(m, p.latitudeDegreesGroupIndex);
        if (p.latitudeMinutesGroupIndexSpecified)
          latMin = GetDoubleFromGroup(m, p.latitudeMinutesGroupIndex);
        if (p.latitudeSecondsGroupIndexSpecified)
          latSec = GetDoubleFromGroup(m, p.latitudeSecondsGroupIndex);

        lngDeg = GetDoubleFromGroup(m, p.longitudeDegreesGroupIndex);
        if (p.longitudeMinutesGroupIndexSpecified)
          lngMin = GetDoubleFromGroup(m, p.longitudeMinutesGroupIndex);
        if (p.longitudeSecondsGroupIndexSpecified)
          lngSec = GetDoubleFromGroup(m, p.longitudeSecondsGroupIndex);

        if (p.isSouthFlagGroupIndexSpecified)
          isS = GetFlagFromGroup(m, p.isSouthFlagGroupIndex);
        if (p.isWestFlagGroupIndexSpecified)
          isW = GetFlagFromGroup(m, p.isWestFlagGroupIndex);

        latDeg = latDeg + latMin / 60 + latSec / 3600;
        if (isS)
          latDeg = -latDeg;
        lngDeg = lngDeg + lngMin / 60 + lngSec / 3600;
        if (isW)
          lngDeg = -lngDeg;

        point = new PointLatLng(latDeg, lngDeg);
        lblResult.Content =
          string.Format("{0:f5} {1:f5}", (double)point.Value.Lat, (double)point.Value.Lng);
      }
    }

    private bool GetFlagFromGroup(Match m, int groupIndex)
    {
      return m.Groups[groupIndex].Success;
    }

    private readonly CultureInfo enUs = CultureInfo.GetCultureInfo("en-US");
    private double GetDoubleFromGroup(Match m, int groupIndex)
    {
      if (m.Groups[groupIndex].Success == false)
        return double.NaN;
      double ret;
      bool res;

      res = double.TryParse(m.Groups[groupIndex].Value, out ret);
      if (!res)
      {
        res = double.TryParse(m.Groups[groupIndex].Value,
          NumberStyles.Any,
          enUs,
          out ret);
      }
      if (!res)
        return double.NaN;
      else
        return ret;
    }

    private void btnOk_Click(object sender, RoutedEventArgs e)
    {
      this.DialogResult = true;
      this.Close();
    }
  }
}
